package io.renren.common.utils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;

import org.jpos.iso.ISOException;
import org.jpos.iso.ISOUtil;


/**
 * 本类主要是一个工具类，方法多是java基本类型与字节之间的转换，或加解密，或协议中需要填充补码等方法。
 *
 * @author caofeng
 *
 */
public class MacUtils {

	/**
	 * int转byte
	 *
	 * @param n
	 *            int类型值
	 * @return byte类型值
	 */
	public static byte[] int2byte(int n) {
		byte b[] = new byte[4];
		b[0] = (byte) (n >> 24);
		b[1] = (byte) (n >> 16);
		b[2] = (byte) (n >> 8);
		b[3] = (byte) n;
		return b;
	}

	/**
	 * byte转int
	 *
	 * @param b
	 *            byte类型值
	 * @param offset
	 *            偏移量
	 * @return int类型值
	 */
	public static int byte2int(byte b[], int offset) {
		return b[offset + 3] & 0xff | (b[offset + 2] & 0xff) << 8
				| (b[offset + 1] & 0xff) << 16 | (b[offset] & 0xff) << 24;
	}

	/**
	 * long转byte
	 *
	 * @param n
	 *            long类型值
	 * @return byte类型值
	 */
	public static byte[] long2byte(long n) {
		byte b[] = new byte[8];
		b[0] = (byte) (int) (n >> 56);
		b[1] = (byte) (int) (n >> 48);
		b[2] = (byte) (int) (n >> 40);
		b[3] = (byte) (int) (n >> 32);
		b[4] = (byte) (int) (n >> 24);
		b[5] = (byte) (int) (n >> 16);
		b[6] = (byte) (int) (n >> 8);
		b[7] = (byte) (int) n;
		return b;
	}

	/**
	 * byte转long
	 *
	 * @param b
	 *            byte类型值
	 * @return long类型值
	 */
	public static long byte2long(byte b[]) {
		return (long) b[7] & (long) 255 | ((long) b[6] & (long) 255) << 8
				| ((long) b[5] & (long) 255) << 16
				| ((long) b[4] & (long) 255) << 24
				| ((long) b[3] & (long) 255) << 32
				| ((long) b[2] & (long) 255) << 40
				| ((long) b[1] & (long) 255) << 48 | (long) b[0] << 56;
	}

	/**
	 * byte转short
	 *
	 * @param b
	 *            byte类型值
	 * @return short类型值
	 */
	public static short byte2Short(byte[] b) {
		return (short) (((b[0] & 0xff)) << 8 | (b[1] & 0xff));
	}

	/**
	 * short转byte
	 *
	 * @param s
	 *            short类型值
	 * @return byte类型值
	 */
	public static byte[] short2Byte(short s) {
		byte[] b = new byte[2];
		b[1] = (byte) (0xff & s);
		b[0] = (byte) ((0xff00 & s) >> 8);

		return b;
	}

	/**
	 * byte转无符号int
	 *
	 * @param b
	 *            byte类型值
	 * @return 无符号int
	 */
	public static int byte2NotExpressionInt(byte[] b) {
		return b[1] & 0xff | (b[0] & 0xff) << 8 | (0x00 & 0xff) << 16
				| (0x00 & 0xff) << 24;
	}

	/**
	 * byte转无符号long
	 *
	 * @param b
	 *            byte类型值
	 * @return 无符号long
	 */
	public static long byte2NotExpressionLong(byte[] b) {
		return (long) b[3] & (long) 255 | ((long) b[2] & (long) 255) << 8
				| ((long) b[1] & (long) 255) << 16
				| ((long) b[0] & (long) 255) << 24
				| ((long) 0x00 & (long) 255) << 32
				| ((long) 0x00 & (long) 255) << 40
				| ((long) 0x00 & (long) 255) << 48 | (long) 0x00 << 56;
	}

	/**
	 * 单字节转int
	 *
	 * @param b
	 *            单byte类型值
	 * @return int类型值
	 */
	public static int singleByte2int(byte b) {
		return b & 0xff;
	}

	/**
	 * int转单字节
	 *
	 * @param i
	 *            int类型值
	 * @return 单byte类型值
	 */
	public static byte int2singleByte(int i) {
		return (byte) (0xff & i);
	}

	/**
	 * string类型转bcd类型后所占字节的长度
	 *
	 * @param strLength
	 *            string类型所占字节的长度
	 * @return 转换bcd类型后所占字节的长度
	 */
	public static int str2bcdLength(int strLength) {
		int bcdLength = strLength / 2;
		if (strLength % 2 != 0) {
			bcdLength += 1;
		}

		return bcdLength;
	}

	/**
	 * 不足len长度的字符串右补空格
	 *
	 * @param s
	 *            源字符串
	 * @param len
	 *            目标长度
	 * @return 补码后的字符串
	 */
	public static String blankpadRight(String s, int len) {
		if (null == s) {
			return null;
		}
		StringBuffer d = new StringBuffer(s);
		while (d.toString().getBytes().length < len)
			d.append(' ');
		return d.toString();
	}

	/**
	 * 不足len长度的字符串右补空格
	 *
	 * @param s
	 *            源字符串
	 * @param len
	 *            目标长度
	 * @return 补码后的字符串
	 */
	public static String zeropadLeft(String s, int len) {
		if (null == s) {
			return null;
		}
		int s_l = s.getBytes().length;
		StringBuffer d = new StringBuffer();
		while (d.toString().getBytes().length + s_l < len)
			d.append("0");
		d.append(s);
		return d.toString();
	}

	/**
	 * 不足size大小的字节右补0x00
	 *
	 * @param b
	 *            源字节数组
	 * @param size
	 *            目标大小
	 * @return 补码后的字节
	 */
	public static byte[] zerobytepadRight(byte[] b, int size) {
		byte[] bytes = new byte[size];
		System.arraycopy(b, 0, bytes, 0, b.length);

		for (int i = 0; i < size - b.length; i++) {
			System.arraycopy(new byte[] { (byte) 0x00 }, 0, bytes,
					b.length + i, 1);
		}

		return bytes;
	}

	/**
	 * 将“[aa,bb][cc,dd]”这样的格式分割成aa,bb和cc,dd两个字符串存入arraylist
	 *
	 * @param str
	 *            需要分割的字符串
	 * @return 分割后的arraylist
	 */
	public static ArrayList strTolist(String str) {
		if (null == str) {
			return null;
		}
		ArrayList dataList = new ArrayList();
		Pattern p = Pattern.compile("(?<=\\[)(.*?)(?=\\])"); // 行正则表达式
		Matcher m = p.matcher(str);
		while (m.find()) {
			dataList.add(m.group().trim());
		}

		return dataList;
	}

	/**
	 * 过滤字符串中的字符，只保留数字
	 *
	 * @param str
	 *            需要被过滤得字符串
	 * @return 过滤后的字符串
	 */
	public static String filterChar(String str) {
		if (null == str) {
			return null;
		}
		Pattern p = Pattern.compile("(\\d)*"); // 字段中所有的数字，用"^(\\d)*字段中第一组数字"
		Matcher m = p.matcher(str);
		StringBuffer sbResult = new StringBuffer();
		while (m.find()) {
			sbResult.append(m.group().trim());
		}

		return sbResult.toString();
	}

	/**
	 * 生成mac值
	 *
	 * @param macKey
	 *            mac密钥
	 * @param sourceBytes
	 *            源数据字节
	 * @return mac值
	 */
	public static byte[] makeMAC(byte[] macKey, byte[] sourceBytes) {
		byte[] mab = sourceBytes;
		final int BLOCK_LENGTH = 8;
		// 计算mab的大小
		if (sourceBytes.length % BLOCK_LENGTH != 0
				|| sourceBytes.length <= BLOCK_LENGTH) {
			int mabSize = (sourceBytes.length / BLOCK_LENGTH + 1)
					* BLOCK_LENGTH;
			if (sourceBytes.length < BLOCK_LENGTH) {
				mabSize = 2 * BLOCK_LENGTH;
			}
			// 将mab不足大小的地方填充0x00
			mab = new byte[mabSize];
			System.arraycopy(sourceBytes, 0, mab, 0, sourceBytes.length);
			byte[] fillBytes = { (byte) 0x00 };
			for (int i = 0; i < mabSize - sourceBytes.length; i++) {
				System.arraycopy(fillBytes, 0, mab, sourceBytes.length + i,
						fillBytes.length);
			}
		}
		// System.out.println("mab-----------"+ISOUtil.hexdump(mab));
		// 进行异或运算
		byte[] tmpBlock1 = new byte[BLOCK_LENGTH];
		byte[] tmpBlock2 = new byte[BLOCK_LENGTH];
		byte[] xorResultBlock = new byte[BLOCK_LENGTH];
		System.arraycopy(mab, 0, tmpBlock1, 0, BLOCK_LENGTH);
		System.arraycopy(mab, BLOCK_LENGTH, tmpBlock2, 0, BLOCK_LENGTH);
		xorResultBlock = byteXOR(tmpBlock1, tmpBlock2);
		// System.out.println("xor1----------"+ISOUtil.hexdump(xorResultBlock));
		for (int j = 2; j < mab.length / BLOCK_LENGTH; j++) {
			byte[] tmpBlock3 = new byte[BLOCK_LENGTH];
			System.arraycopy(mab, j * BLOCK_LENGTH, tmpBlock3, 0, BLOCK_LENGTH);
			xorResultBlock = byteXOR(xorResultBlock, tmpBlock3);
			// System.out.println("xor"+j+"----------"+ISOUtil.hexdump(xorResultBlock));
		}
		// System.out.println("xorResultBlock-----------"+ISOUtil.hexdump(xorResultBlock));
		// bcd2str
		byte[] resultBlock = BcdToAscii(xorResultBlock);
		// System.out.println("resultBlock-----------"+ISOUtil.hexdump(resultBlock));
		// resultBlock前8个字节用macKey加密
		byte[] frontResultBlock = new byte[BLOCK_LENGTH];
		System.arraycopy(resultBlock, 0, frontResultBlock, 0, BLOCK_LENGTH);
		byte[] desResultBytes = encryptForDES(macKey, frontResultBlock);
		// System.out.println("desResultBytes-----------"+ISOUtil.hexdump(desResultBytes));
		// 加密后的结果与resultBlock后8个字节异或
		byte[] backResultBlock = new byte[BLOCK_LENGTH];
		System.arraycopy(resultBlock, BLOCK_LENGTH, backResultBlock, 0,
				BLOCK_LENGTH);
		byte[] xorTmpBlock = byteXOR(desResultBytes, backResultBlock);
		// System.out.println("xorTmpBlock-----------"+ISOUtil.hexdump(xorTmpBlock));
		// 用异或的结果TEMP BLOCK 再进行一次单倍长密钥算法运算。
		byte[] desXORTmpBlock = encryptForDES(macKey, xorTmpBlock);
		// System.out.println("desXORTmpBlock-----------"+ISOUtil.hexdump(desXORTmpBlock));
		// bcd2str
		byte[] tmpMAC = BcdToAscii(desXORTmpBlock);
		System.out.println("tmpMAC-----------"+ISOUtil.hexdump(tmpMAC));
		//byte[] mac = new byte[BLOCK_LENGTH];
		//System.arraycopy(tmpMAC, 0, mac, 0, BLOCK_LENGTH);

		//return mac;
		return tmpMAC;
	}



	public static String decryptPINData(byte[] pinKey, byte[] cryptoData) {
		//System.out.println("pinKey="+ISOUtil.hexdump(pinKey));
		//System.out.println("cryptoData="+ISOUtil.hexdump(cryptoData));
		byte[] pinBytes = decryptForDES(pinKey, cryptoData);
		String pinStr = new String(BcdToAscii(pinBytes));
		int len = Integer.parseInt(pinStr.substring(0, 2));

		return pinStr.substring(2, 2 + len);
	}

	/**
	 * 加密pinData
	 *
	 * @param pinKey
	 *            pin密钥
	 * @param cryptoData
	 *
	 * @return 加密后的密码
	 */
	public static String EncryptPINData(byte[] pinKey, byte[] cryptoData) {
		byte[] pinBytes = decryptForDES(pinKey, cryptoData);
		String pinStr = new String(BcdToAscii(pinBytes));
		int len = Integer.parseInt(pinStr.substring(0, 2));

		return pinStr.substring(2, 2 + len);
	}

	/**
	 * 加密充值单卡号密码
	 *
	 * @param pinKey
	 *            pin密钥
	 * @param cardNumber
	 *            充值单卡号
	 * @param cardNumberLength
	 *            卡号长度
	 * @param cardPassword
	 *            充值单密码
	 * @param cardPasswordLength
	 *            密码长度
	 * @return 加密后的数据
	 */
	public static byte[] encryptMobileRechargeProductData(byte[] pinKey,
														  String cardNumber, int cardNumberLength, String cardPassword,
														  int cardPasswordLength) {
		byte[] sourceBytes = (blankpadRight(cardNumber, cardNumberLength) + blankpadRight(
				cardPassword, cardPasswordLength)).getBytes();
		return encryptForDES(pinKey, sourceBytes);
	}





	/**
	 * 解密充值单卡号密码
	 *
	 * @param mackey
	 *            pin密钥
	 * @param cardNumber
	 *            充值单卡号
	 * @param cardNumberLength
	 *            卡号长度
	 * @param cardPassword
	 *            充值单密码
	 * @param cardPasswordLength
	 *            密码长度
	 * @return 加密后的数据
	 */
	public static byte[] decryptMobileRechargeProductData(byte[] mackey,
														  String cardNumber, int cardNumberLength, String cardPassword,
														  int cardPasswordLength) {
		byte[] sourceBytes = (blankpadRight(cardNumber, cardNumberLength) + blankpadRight(
				cardPassword, cardPasswordLength)).getBytes();
		return decryptForDES(mackey, sourceBytes);
	}

	/**
	 * 字节异或运算
	 *
	 * @param bytes1
	 * @param bytes2
	 * @return 异或后的bytes
	 */
	private static byte[] byteXOR(byte[] bytes1, byte[] bytes2) {
		if (bytes1.length != bytes2.length) {
			return null;
		}
		byte[] resultBytes = new byte[bytes1.length];
		for (int i = 0; i < bytes1.length; i++) {
			resultBytes[i] = (byte) (bytes1[i] ^ bytes2[i]);
		}

		return resultBytes;
	}




	private static byte[] encryptForDES(byte[] key, byte[] sourceBytes) {
		String Algorithm = "DES";
		byte[] resultBytes = null;
		try {
			SecretKeyFactory keyFactory = SecretKeyFactory
					.getInstance(Algorithm);
			Cipher c = Cipher.getInstance(Algorithm + "/ECB/NoPadding");
			DESKeySpec deskey = new DESKeySpec(key);
			SecretKey theKey = keyFactory.generateSecret(deskey);
			c.init(Cipher.ENCRYPT_MODE, theKey);
			resultBytes = c.doFinal(sourceBytes);
		} catch (Exception e) {
			e.printStackTrace();
		}

		return resultBytes;
	}

	/**
	 * des解密
	 *
	 * @param key
	 *            密钥
	 * @param sourceBytes
	 *            密文
	 * @return 源字节
	 */
	private static byte[] decryptForDES(byte[] key, byte[] sourceBytes) {
		String Algorithm = "DES";
		byte[] resultBytes = null;
		try {
			SecretKeyFactory keyFactory = SecretKeyFactory
					.getInstance(Algorithm);
			Cipher c = Cipher.getInstance(Algorithm + "/ECB/NoPadding");
			DESKeySpec deskey = new DESKeySpec(key);
			SecretKey theKey = keyFactory.generateSecret(deskey);
			c.init(Cipher.DECRYPT_MODE, theKey);
			resultBytes = c.doFinal(sourceBytes);
		} catch (Exception e) {
			e.printStackTrace();
		}
		// System.out.println("key-----------"+ISOUtil.hexdump(key));
		// System.out.println("sourceBytes-----------"+ISOUtil.hexdump(sourceBytes));
		// System.out.println("resultBytes-----------"+ISOUtil.hexdump(resultBytes));

		return resultBytes;
	}

	/**
	 * Compares this byte arrary to the specified object. The result is
	 * <code>true</code> if and only if the argument is not <code>null</code>
	 * and is a <code>String</code> object that represents the same sequence
	 * of characters as this object.
	 *
	 * @param src
	 *            the first byte array
	 * @param dst
	 *            the second byte array against.
	 * @return <code>true</code> if the <code>String </code>are equal;
	 *         <code>false</code> otherwise.
	 */
	public static boolean equalByteArray(byte[] src, byte[] dst) {
		return equalByteArray(src, 0, src.length, dst, 0, dst.length);
	}

	public static boolean equalByteArray(byte[] src, int srcOffset, int srcLen,
										 byte[] dst, int dstOffset, int dstLen) {
		if (srcLen != dstLen
				|| compareByteArray(src, srcOffset, srcLen, dst, dstOffset,
				dstLen) != 0)
			return false;
		else
			return true;
	}

	public static int compareByteArray(byte[] src, byte[] dst) {
		return compareByteArray(src, 0, src.length, dst, 0, dst.length);
	}

	public static int compareByteArray(byte[] src, int srcOffset, byte[] dst,
									   int dstOffset, int length) {
		return compareByteArray(src, srcOffset, length, dst, dstOffset, length);
	}

	/**
	 * Compares two byte array lexicographically..
	 *
	 * @param src
	 *            the byte array
	 * @param srcOffset
	 *            the start position of the first byte array
	 * @param dst
	 *            the byte array
	 * @param dstOffset
	 *            the start position of the second byte array
	 * @return the value <code>0</code> if the argument string is equal to
	 *         this string; a value less than <code>0</code> if this string is
	 *         lexicographically less than the string argument; and a value
	 *         greater than <code>0</code> if this string is lexicographically
	 *         greater than the string argument.
	 */
	public static int compareByteArray(byte[] src, int srcOffset, int srcLen,
									   byte[] dst, int dstOffset, int dstLen) {
		int n = Math.min(srcLen, dstLen);

		char c1, c2;

		for (int i = 0; i < n; i++) {
			// compare the byte
			c1 = (char) (src[srcOffset + i] & 0xFF);
			c2 = (char) (dst[dstOffset + i] & 0xFF);
			if (c1 != c2) {
				return c1 - c2;
			}
		}

		return srcLen - dstLen;
	}

	/**
	 * BCD类型转ASCII类型
	 *
	 * @param bcdByte
	 *            bcd编码字节
	 * @return ascii编码字节
	 */
	public static byte[] BcdToAscii(byte[] bcdByte) {
		byte[] asciiByte = new byte[bcdByte.length * 2];
		BcdToAscii(bcdByte, 0, asciiByte, 0, asciiByte.length, 0);
		return asciiByte;
	}

	public static void BcdToAscii(byte[] bcd_buf, int offset, byte[] ascii_buf,
								  int asc_offset, int conv_len, int type) // conv_len： 转换后ascii的长度；
	// type = 0 右补0
	{
		int cnt;
		int bcdOffset = offset;
		int asciiOffset = asc_offset;

		if (conv_len > (bcd_buf.length * 2))
			conv_len = (bcd_buf.length * 2);

		if (((conv_len & 0x01) > 0) && (type > 0)) {
			cnt = 1;
			conv_len++;
		} else
			cnt = 0;

		for (; cnt < conv_len; cnt++, asciiOffset++) {
			ascii_buf[asciiOffset] = (byte) (((cnt & 0x01) > 0) ? (bcd_buf[bcdOffset++] & 0x0f)
					: ((bcd_buf[bcdOffset] & 0xFF) >>> 4));
			ascii_buf[asciiOffset] += (byte) ((ascii_buf[asciiOffset] > 9) ? (65 - 10)
					: 48); // 65 = 'A' 48 = '0'
		}
	}

	/**
	 * ASCII类型转BCD类型
	 *
	 * @param ascii
	 * @param bcd
	 * @return
	 */
	public static boolean AsciiToBcd(byte[] ascii, byte[] bcd) {
		if (ascii != null && bcd != null) {
			int byteLen = bcd.length * 2;
			byteLen = (byteLen > ascii.length) ? ascii.length : byteLen;
			return AsciiToBcd(ascii, 0, bcd, 0, byteLen, 0);
		} else
			return false;
	}

	public static boolean AsciiToBcd(byte[] ascii_buf, int asc_offset,
									 byte[] bcd_buf, int bcd_offset, int conv_len, int type) {
		if (bcd_offset < 0 || asc_offset < 0 || conv_len < 0
				|| ascii_buf == null || bcd_buf == null
				|| bcd_offset >= bcd_buf.length
				|| asc_offset >= ascii_buf.length)
			return false;
		int cnt;
		byte ch, ch1;
		int bcdOffset = bcd_offset;
		int asciiOffset = asc_offset;

		if (((conv_len & 0x01) > 0) && (type > 0))
			ch1 = 0;
		else
			ch1 = 0x55;

		for (cnt = 0; cnt < conv_len; asciiOffset++, cnt++) {
			if (ascii_buf[asciiOffset] >= 97) // 97 = 'a'
			{
				ch = (byte) (ascii_buf[asciiOffset] - 97 + 10); // 97 = 'a'
			} else {
				if (ascii_buf[asciiOffset] >= 65) // 65 = 'A'
					ch = (byte) ((ascii_buf[asciiOffset]) - 65 + 10); // 65 =
					// 'A'
				else if (ascii_buf[asciiOffset] >= 48) // 48 = '0'
					ch = (byte) ((ascii_buf[asciiOffset]) - 48); // 48 = '0'
				else
					ch = 0;
			}

			if (ch1 == 0x55)
				ch1 = ch;
			else {
				// *bcd_buf++=ch1<<4 | ch;
				bcd_buf[bcdOffset++] = (byte) ((ch1 << 4) | ch);
				ch1 = 0x55;
			}
		}
		if (ch1 != 0x55)
			bcd_buf[bcdOffset] = (byte) (ch1 << 4);
		return true;
	}

	/**
	 * 反转字节
	 *
	 * @param bytes
	 *            源字节
	 * @return 反转后的字节
	 */
	public static byte[] reverseByteArray(byte[] bytes) {

		byte[] resultBytes = new byte[bytes.length];
		for (int i = 0; i < bytes.length; i++) {
			resultBytes[i] = bytes[bytes.length - i - 1];
		}

		return resultBytes;
	}

	/**
	 * Method converting byte array into int.
	 *
	 * @param src
	 *            byte array to be converted.
	 *
	 */
	public static int byte4ToInt(byte[] src) {
		return byte4ToInt(src, 0);
	}

	public static int byte4ToInt(byte[] src, int offset) {
		if (null == src || offset < 0 || offset > src.length)
			throw new NullPointerException("invalid byte array ");
		if ((src.length - offset) < 4)
			throw new IndexOutOfBoundsException("invalid len: " + src.length);

		int number = ((((src[offset + 3] & 0xff) << 8 | (src[offset + 2] & 0xff)) << 8) | (src[offset + 1] & 0xff)) << 8
				| (src[offset + 0] & 0xff);

		return number;
	}

	/**
	 * 根据需要的长度字符串前补加0
	 *
	 * @param str
	 *            源字符串
	 * @param len
	 *            需要的长度
	 * @return 补码后的字符串
	 * @throws ISOException
	 */
	public static String toVariableLengthString(String str, int len)
			throws ISOException {
		StringBuffer varLenSB = new StringBuffer();
		if (0 == len) {
			return str;
		}
		if (null == str || 0 == str.getBytes().length) {
			return ISOUtil.zeropad("0", len);
		}
		String lenStr = String.valueOf(str.getBytes().length);
		varLenSB.append(ISOUtil.zeropad(lenStr, len));
		varLenSB.append(str);

		return varLenSB.toString();
	}

	/**
	 * hex转byte
	 *
	 * @param data
	 *            hex字符串
	 * @return byte数组
	 */
	public static byte[] hexToByte(String data) {
		int len = data.length();
		byte[] ba = new byte[len / 2];
		int i = 0, j = 0, c;
		while (i < len) {
			c = Character.digit(data.charAt(i++), 16) << 4;
			c = c + Character.digit(data.charAt(i++), 16);
			ba[j++] = (byte) c;
		}
		return ba;
	}

	public static String readUnionPayCard(String cardNum, String rep) {
		if (cardNum == null)
			return null;
		else if (cardNum.indexOf(rep) != -1)
			return cardNum.substring(0, cardNum.indexOf(rep));
		else
			return cardNum;
	}


	/*
	 * 获取卡号
	 *
	 */
	public static String getCardNumber(String Track2Data) {
		if (Track2Data == null)
			return null;
		Track2Data = Track2Data.replace("*", "=");
		String[] s = Track2Data.split("=");
		String cardNumber = s[0];
		return cardNumber;
	}


	/** *//**
	 * @函数功能: 10进制串转为BCD码
	 * @输入参数: 10进制串
	 * @输出结果: BCD码
	 */
	public static byte[] str2Bcd(String asc) {
		int len = asc.length();
		int mod = len % 2;

		if (mod != 0) {
			asc = "0" + asc;
			len = asc.length();
		}

		byte abt[] = new byte[len];
		if (len >= 2) {
			len = len / 2;
		}

		byte bbt[] = new byte[len];
		abt = asc.getBytes();
		int j, k;

		for (int p = 0; p < asc.length()/2; p++) {
			if ( (abt[2 * p] >= '0') && (abt[2 * p] <= '9')) {
				j = abt[2 * p] - '0';
			} else if ( (abt[2 * p] >= 'a') && (abt[2 * p] <= 'z')) {
				j = abt[2 * p] - 'a' + 0x0a;
			} else {
				j = abt[2 * p] - 'A' + 0x0a;
			}

			if ( (abt[2 * p + 1] >= '0') && (abt[2 * p + 1] <= '9')) {
				k = abt[2 * p + 1] - '0';
			} else if ( (abt[2 * p + 1] >= 'a') && (abt[2 * p + 1] <= 'z')) {
				k = abt[2 * p + 1] - 'a' + 0x0a;
			}else {
				k = abt[2 * p + 1] - 'A' + 0x0a;
			}

			int a = (j << 4) + k;
			byte b = (byte) a;
			bbt[p] = b;
		}
		return bbt;
	}



	/**
	 * 根据需要的长度字符串前补加0
	 * @param str	源字符串
	 * @param len	需要的长度
	 * @return	补码后的字符串
	 * @throws ISOException
	 */
	public static String left0(String str,int len){
		if(str == null){
			str = "";
			for(int i=0;i<len;i++){
				str = str + "0";
			}
			return str;
		}
		if(str.length()>=len){
			return str;
		}
		int j=len-str.length();
		for(int i=0;i<j;i++){
			str="0"+str;
		}
		return str;
	}


	public static void main(String[] args) {
		//System.out.println(ISOUtil.hexdump(makeMAC1(str2Bcd("CB4E78F2F2994C45"), str2Bcd("02006020040020C01811162180010000406436300000000001303231292180010000406436D111111111111030303033363536303030303030303030303030303030322456F186E21F62A80000000000000000000801000001"))));

		//makeMAC 生成MAC
		System.out.println(ISOUtil.dumpString(makeMAC("a12345678".getBytes(), "1()24tgargdret43".getBytes())));

	}
}
